﻿using System;
using BaseDeDatos.Exceptions;
using NHibernate;
using NHibernate.Cfg;


namespace BaseDeDatos
{
    public class BD
    {
        #region metodos
        /// <summary>
        /// funcion que devuelve un objeto haciendo una consulta con la base de datos
        /// </summary>
        /// <param name="tabla">establece la tabla a la que se le va a hacer la consulta</param>
        /// <param name="parametro">establece el valor de la columna a la que se va a consultar</param>
        /// <param name="columna">establece la columna de la tabla a la que se va a consultar</param>
        /// <returns>
        /// si se encuentra el registro que se esta buscando devuelve el objeto
        /// sino devuelve null
        /// </returns>
        public static object Login(String tabla, String parametro, String columna)
        {
            ISessionFactory sessionFactory = null;
            Configuration cfg = new Configuration();
            ISession session = null;
            try
            {
                cfg.AddAssembly("BaseDeDatos");
                sessionFactory = cfg.BuildSessionFactory();
                ITransaction transaction = null;
                session = sessionFactory.OpenSession();
                transaction = session.BeginTransaction();
                System.Collections.IList a;
                String query = "from " + tabla + " where " + columna + "='" + parametro + "'";
                a = session.Find(query);
                return a[0];
            }
            catch (ArgumentException ae)  //alguno de los argumentos es incorrectos
            {
                throw (new NoExisteException("Los argumentos en la consulta son incorrectos", ae));
            }
            catch (ADOException ade)  //Error de conexion (hay que buscar)
            {
                throw (new ConexionFallidaException("Ocurrio un error en la base de datos",ade));
            }
            catch (TransactionException te)  //cuando no se pudo realizar la transaccion por alguna razon
            {
                throw (new BDException("No se pudo realizar la transaccion", te));
            }
            catch (HibernateException ne)
            {
                throw (new BDException("Ocurrio un error en la Base de Datos", ne));
            }
            catch (Exception ex)
            {
                throw (new BDException("Ocurrio algun error en la base de datos", ex));
            }
            finally
            {
                if (session != null) session.Close();
            }
        }


        /// <summary>
        /// Almacena a una persona en la base de datos.
        /// </summary>
        /// <param name="person">Objeto del tipo persona</param>
        /// <returns>true si se realizo la insercion de forma correcta y false
        /// si no se pudo realizar la insercion</returns>
        public static void SavePerson(Object person)
        {
            ISessionFactory sessionFactory = null;
            Configuration cfg = new Configuration();
            ISession session = null;
            ITransaction transaction = null;
            try
            {
                cfg.AddAssembly("BaseDeDatos");
                sessionFactory = cfg.BuildSessionFactory();
                session = sessionFactory.OpenSession();
                transaction = session.BeginTransaction();
                session.Save(person);
                session.Flush();
                transaction.Commit();


            }
            catch (TransactionException te)  //cuando no se pudo realizar la transaccion por alguna razon
            {
                throw (new BDException("No se pudo realizar la transaccion", te));
            }
            catch (ADOException ade)  //Error de conexion (hay que buscar)
            {
                throw (new ConexionFallidaException("Ocurrio un error en la base de datos", ade));
            }
            catch (HibernateException ne)
            {
                throw (new BDException("Ocurrio un error en la Base de Datos",ne));
            }
            catch (Exception ex)
            {
                throw (new UsuarioNoInsertadoException("Ocurrio algun error en la base de datos", ex));
                transaction.Rollback();
                
            }
            finally
            {
                if (session != null) { session.Close(); }
            }
        }

        /// <summary>
        /// Almacena a una persona en la base de datos.
        /// </summary>
        /// <param name="person">Objeto del tipo persona</param>
        /// <returns>true si se realizo la insercion de forma correcta y false
        /// si no se pudo realizar la insercion</returns>
        public static void Update(Object person)
        {
            ISessionFactory sessionFactory = null;
            Configuration cfg = new Configuration();
            ISession session = null;
            ITransaction transaction = null;
            try
            {
                cfg.AddAssembly("BaseDeDatos");
                sessionFactory = cfg.BuildSessionFactory();
                session = sessionFactory.OpenSession();
                transaction = session.BeginTransaction();
                session.SaveOrUpdate(person);
                session.Flush();
                transaction.Commit();
            }
            catch (ADOException ade)  //Error de conexion (hay que buscar)
            {
                throw (new ConexionFallidaException("Ocurrio un error en la base de datos", ade));
            }
            catch (TransactionException te)  //cuando no se pudo realizar la transaccion por alguna razon
            {
                throw (new BDException("No se pudo realizar la transaccion", te));
            }
            catch (HibernateException ne)
            {
                throw (new BDException("Ocurrio un error en la Base de Datos", ne));
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw (new UsuarioNoModificadoException("Ocurrio un error en la Base de Datos",ex));
            }
            finally
            {
                if (session != null) { session.Close(); }
            }
        }

        /// <summary>
        /// Realiza consultas sobre la BD.
        /// </summary>
        /// <param name="query">String que contiene la sentencia sql a ejecutar</param>
        /// <returns>retorna el objeto con la informacion encontrada</returns>
        public static Object Consultar(String query)
        {
            System.Collections.IList resul;
            ISessionFactory sessionFactory = null;
            Configuration cfg = new Configuration();
            ISession session = null;
            ITransaction transaction = null;
            try
            {
                cfg.AddAssembly("BaseDeDatos");
                sessionFactory = cfg.BuildSessionFactory();
                session = sessionFactory.OpenSession();
                transaction = session.BeginTransaction();
                resul = session.Find(query);
                return resul;
            }
            catch (ArgumentException ae)  //alguno de los argumentos es incorrectos
            {
                throw (new BDException("Los argumentos en la consulta son incorrectos", ae));
            }
            catch (ADOException ade)  //Error de conexion (hay que buscar)
            {
                throw (new ConexionFallidaException("Ocurrio un error en la base de datos", ade));
            }
            catch (TransactionException te)  //cuando no se pudo realizar la transaccion por alguna razon
            {
                throw (new BDException("No se pudo realizar la transaccion", te));
            }
            catch (HibernateException ne)
            {
                throw (new BDException("Ocurrio un error en la Base de Datos", ne));
            }
            catch (Exception ex)
            {
                throw (new BDException("Ocurrio algun error en la base de datos", ex));
            }
            finally
            {
                if (session != null) { session.Close(); }
            }
            
        }

        #endregion
    }
}
